package com.lej.core.utils.extention

import android.content.Context
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.View
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.core.net.toUri
import androidx.core.text.HtmlCompat
import com.alibaba.android.arouter.launcher.ARouter
import com.lej.core.base.app
import com.lej.core.base.currentActivity
import com.lej.core.common.TITLE
import com.lej.core.common.WEB_URL
import com.lej.core.dsl.dp
import com.lej.core.router.CRouter
import com.lej.core.utils.KLog
import com.lej.core.utils.ToastUtils
import com.lej.core.utils.constant.RegexConstants
import com.lej.core.utils.reportIt
import com.qmuiteam.qmui.span.QMUIAlignMiddleImageSpan
import com.qmuiteam.qmui.span.QMUIMarginImageSpan
import com.tencent.bugly.crashreport.BuglyLog
import java.text.SimpleDateFormat
import java.util.*

/** stackIndex 0代表调用logI的那一行 */
fun String.logI(tag: String, stackIndex: Int = 0) =
    apply {
        if (app.isDebug) KLog.i("sss_$tag", this, 6 + stackIndex)
        else BuglyLog.i(tag, this)
    }

fun String.logD(tag: String) =
    apply {
        if (app.isDebug) KLog.d("sss_$tag", this)
        else BuglyLog.d(tag, this)
    }

fun Throwable.logE(tag: String) = apply { KLog.e("sss_$tag", this);this.reportIt() }

fun String?.toast() = apply {
    if (this.isNullOrEmpty()) return@apply
    ToastUtils.show(this)
}

fun String.toDate(formatStr: String) =
    kotlin.runCatching { SimpleDateFormat(formatStr, Locale.getDefault()).parse(this) }.getOrNull()

fun String.toCalendar(formatStr: String) =
    kotlin.runCatching { SimpleDateFormat(formatStr, Locale.getDefault()).parse(this) }.getOrNull()?.run {
        Calendar.getInstance().also {
            it.time = this
        }
    }

fun String?.isPhoneNumber() =
    if (this == null) false else RegexConstants.REGEX_MOBILE_EXACT.toRegex().matches(this)

fun String?.isPhoneNumberLoose() =
    if (this == null) false else RegexConstants.REGEX_MOBILE_SIMPLE.toRegex().matches(this)

/**文字着色*/
fun String.tintAllText(@ColorInt color: Int): SpannableString {
    val spannableString = SpannableString(this)
    val colorFSpan = ForegroundColorSpan(color)
    spannableString.setSpan(colorFSpan, 0, this.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
    return spannableString
}

fun String.underLine(): Spanned =
    HtmlCompat.fromHtml("<u>${this}</u>", HtmlCompat.FROM_HTML_MODE_LEGACY)

/**文字颜色设置 [tints] 文字和颜色对 first 变色文字，second 颜色*/
fun String.tintText(isBold: Boolean = false, vararg tints: Pair<String, Int>): SpannableString {

    val spans: List<Pair<String, Array<Any>>> = tints.map {
        it.first to if (isBold) arrayOf<Any>(
            ForegroundColorSpan(it.second),
            StyleSpan(Typeface.BOLD)
        ) else arrayOf<Any>(ForegroundColorSpan(it.second))
    }
    return spanText(*spans.toTypedArray())
}

/**文字颜色设置 [tints] 文字和颜色对 first 变色文字，second 颜色*/
//fun String.urlClick(vararg tints: Pair<String, Int>): SpannableString {
//
//    val res = "(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?".toRegex().find(this) ?: return SpannableString(this)
//    val spannableString = SpannableString(this)
//    val span =object: ClickableSpan() {
//        override fun onClick(widget: View) {
//            ARouter.getInstance()
//                .build(CRouter.webView)
//                .withString(WEB_URL, res.value)
//                .withString(TITLE, "用户充值协议")
//                .navigation(currentActivity)
//        }
//
////        override fun updateDrawState(ds: TextPaint) {
////            super.updateDrawState(ds)
////            ds.color = Color.WHITE
////        }
//    }
//    spannableString.setSpan(span, res.range.first, res.range.last, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
//    return spannableString
//}
fun CharSequence.urlClick(vararg tints: Pair<String, Int>): SpannableString {

    val res =
        "(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?".toRegex()
            .find(this) ?: return SpannableString(this)
    val spannableString = SpannableString(this)
    val span = object : ClickableSpan() {
        override fun onClick(widget: View) {
            ARouter.getInstance()
                .build(CRouter.webView)
                .withString(WEB_URL, res.value)
                .withString(TITLE, "用户充值协议")
                .navigation(currentActivity)
        }

//        override fun updateDrawState(ds: TextPaint) {
//            super.updateDrawState(ds)
//            ds.color = Color.WHITE
//        }
    }
    spannableString.setSpan(
        span,
        res.range.first,
        res.range.last,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
    )
    return spannableString
}

fun CharSequence.urlTagClick(tag: CharSequence, url: String): SpannableString {
    val res = "$tag".toRegex()
        .find(this) ?: return SpannableString(this)
    val spannableString = SpannableString(this)
    val span = object : ClickableSpan() {
        override fun onClick(widget: View) {
            currentActivity.router(CRouter.webView) {
                withString(WEB_URL, url)
            }
        }
    }
    spannableString.setSpan(
        span,
        res.range.first,
        res.range.last + 1,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
    )
    return spannableString
}

/**文字颜色设置 [tints] 文字和颜色对 first 变色文字，second 颜色*/
fun String.spanText(vararg pairs: Pair<String, Array<Any>>): SpannableString {
    val spannableString = SpannableString(this)
    pairs.forEach {
        if (it.first.isEmpty())
            return spannableString
        var i = 0
        val spans = it.second
        while (i <= length - it.first.length) {
            val resIndex = indexOf(it.first, i)
            if (resIndex == -1)
                break
            else {
                spans.forEach { span ->
                    spannableString.setSpan(
                        span,
                        resIndex,
                        resIndex + it.first.length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
                i = resIndex + it.first.length
            }
        }
    }
    return spannableString
}

fun String.tintNUmberText(color: Int, isBold: Boolean = false): SpannableString {
    val p = "\\d+".toRegex()
    return tintText(isBold, *(p.findAll(this).map { it.value to color }.toList().toTypedArray()))

}

/**文字颜色设置 [tints] 文字和颜色对 first 变色文字，second 颜色*/
fun String.tintTextWithBold(vararg tints: Pair<String, Int>): SpannableString {
    val spannableString = SpannableString(this)
    tints.forEach {
        if (it.first.isEmpty())
            return spannableString
        var i = 0
        val colorFSpan = ForegroundColorSpan(it.second)
        while (i < length - it.first.length) {
            val resIndex = indexOf(it.first, i)
            if (resIndex == -1)
                break
            else {
                spannableString.setSpan(
                    colorFSpan,
                    resIndex,
                    resIndex + it.first.length,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                i = resIndex + it.first.length
            }
        }
    }
    return spannableString
}

fun String.addUrlParams(vararg pairs: Pair<String, Any>) = addUrlParams(mapOf(*pairs))

/** 网络地址后添加参数 可防止地址后面已经拼接参数地址拼接问题 [map] Map<String, String> 参数集合   */
fun String.addUrlParams(map: Map<String, Any>?): String {
    map ?: return this
    val oldUri = this.toUri()
    val uriBuilder = oldUri.buildUpon()

    map.forEach { (k, v) ->
        if (oldUri.getQueryParameter(k) == null)
            uriBuilder.appendQueryParameter(k, v.toString())
    }
    return uriBuilder.build().toString()
}

fun String?.safe(default: String = "") : String = if (isNullOrEmpty()) default else this

/**设置文本字体大小*/
fun CharSequence.setFontSize(size: Int) = SpannableString(this).apply {
    setSpan(
        AbsoluteSizeSpan(size),
        0,
        length,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
    )
}


/**通过图标获取对应的富文本*/
fun getDrawableSpan(context: Context, @DrawableRes drawableRes: Int, width: Int, height: Int) =
    SpannableString("-").apply {
        val icon = context.getDrawableCompat(drawableRes) ?: return@apply
        icon.setBounds(0, 0, width.dp, height.dp)
        val imageSpan = QMUIMarginImageSpan(icon, QMUIAlignMiddleImageSpan.ALIGN_MIDDLE, 2.dp, 2.dp)
        setSpan(imageSpan, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    }

/**通过图标获取对应的富文本*/
fun Drawable.getDrawableSpan(width: Int, height: Int) =
    SpannableString("-").apply {
        this@getDrawableSpan.setBounds(0, 0, width.dp, height.dp)
        val imageSpan =
            QMUIMarginImageSpan(this@getDrawableSpan, QMUIAlignMiddleImageSpan.ALIGN_MIDDLE, 2.dp, 2.dp)
        setSpan(imageSpan, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    }